Lodash.concat 源码阅读
Lodash 源码阅读(四)
concat
该方法的效果同 Array.concat
var array = [1];
var other = _.concat(array, 2, [3], [[4]]);
console.log(array.concat(2, [3], [[4]])); // => [1, 2, 3, [4]]
console.log(other); // => [1, 2, 3, [4]]
import arrayPush from './_arrayPush.js';
import baseFlatten from './_baseFlatten.js';
import copyArray from './_copyArray.js';
import isArray from './isArray.js';
function concat() {
var length = arguments.length;
if (!length) {
return [];
}
var args = Array(length - 1),
array = arguments[0],
index = length;
while (index--) {
args[index - 1] = arguments[index];
}
return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
}
工具函数
_arrayPush
param1: array
param2: values
两个参数均为数组,将第二个数组中每个值 push 到 第一个参数后面
使用示例
var array = [1, 2, 3, 4];
var values = [5, 6, 7, [8], "9"];
console.log(arrayPush(array, values)); // [1, 2, 3, 4, 5, 6, 7, [8], "9"]
源码
function arrayPush(array, values) {
var index = -1,
length = values.length,
offset = array.length;
// 循环将 values 里的值挨个放到 array 中并返回 array
while (++index < length) {
array[offset + index] = values[index];
}
return array;
}
_copyArray
param1: source
为待复制(浅复制)的数组
param2: array
为目标数组或为空
使用示例
copyArray([1, 2, 3]); // [1, 2, 3]
源码
function copyArray(source, array) {
var index = -1,
length = source.length;
array || (array = Array(length));
while (++index < length) {
// 浅复制
array[index] = source[index];
}
return array;
}
_baseFlatten
param1: array
想要扁平化的数组
param2: depth
扁平化的深度
param3: predicate
判断是否需要扁平化的函数
param4: isStrict
param5: result
使用示例
baseFlatten([1, [2], 3, [4, 5, [6, 7]]], 1); // [1, 2, 3, 4, 5, [6, 7]]
源码
import arrayPush from './_arrayPush.js';
import isFlattenable from './_isFlattenable.js';
function baseFlatten(array, depth, predicate, isStrict, result) {
var index = -1,
length = array.length;
predicate || (predicate = isFlattenable);
result || (result = []);
while (++index < length) {
var value = array[index];
// 如果当前深度大于 0 且当前值是可以扁平化的
if (depth > 0 && predicate(value)) {
if (depth > 1) {
// 递归去扁平化数组
// Recursively flatten arrays (susceptible to call stack limits).
baseFlatten(value, depth - 1, predicate, isStrict, result);
} else {
// depth === 1 时该函数完成了扁平化,进行赋值操作
arrayPush(result, value);
}
} else if (!isStrict) { // 限制哪些没有通过扁平化测试的值,如果不是严格型的就赋值,如果是严格型的就丢弃
result[result.length] = value;
}
}
return result;
}
_isFlattenable
param1: value
待判断是否可以做扁平化操作的值
源码
import Symbol from './_Symbol.js';
import isArguments from './isArguments.js';
import isArray from './isArray.js';
/** Built-in value references. */
var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
function isFlattenable(value) {
return isArray(value) || isArguments(value) ||
!!(spreadableSymbol && value && value[spreadableSymbol]);
}